package com.easylive.web.controller;

import java.awt.*;
import java.io.IOException;

import com.easylive.entity.enums.QueryUserFocusEnum;
import com.easylive.entity.po.UserInfo;
import com.easylive.entity.query.UserFocusQuery;
import com.easylive.entity.response.account.AccountGetUserCountInfoRspVO;
import com.easylive.service.UserFocusService;
import com.easylive.web.annotation.GlobalInterceptor;
import com.easylive.entity.component.RedisComponent;
import com.easylive.entity.constants.Constants;
import com.easylive.entity.dto.TokenUserInfoDto;
import com.easylive.entity.request.account.WebRegisterReqVO;
import com.easylive.entity.response.account.CheckCodeRspVO;
import com.easylive.entity.request.account.WebLoginReqVO;
import com.easylive.entity.vo.ResponseVO;
import com.easylive.exception.BusinessException;
import com.easylive.service.UserInfoService;
import com.easylive.utils.StringTools;
import com.wf.captcha.GifCaptcha;
import com.wf.captcha.base.Captcha;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

/**
 * 用户信息表 Controller
 */
@RestController("accountController")
@RequestMapping("/account")
@Slf4j
public class AccountController extends ABaseController{

	@Resource
	private UserInfoService userInfoService;

	@Resource
	private RedisComponent redisComponent;

	@Resource
	private UserFocusService userFocusService;

	@PostMapping("/checkCode")
	public ResponseVO checkCode() throws IOException, FontFormatException {
		GifCaptcha gifCaptcha = new GifCaptcha(100, 42);
		gifCaptcha.setFont(Captcha.FONT_1);

		String code = gifCaptcha.text();
		log.info("登录验证码：{}", code);

		String captchaBase64 = gifCaptcha.toBase64();
		String checkCodeKey = redisComponent.saveCheckCode(code);

		CheckCodeRspVO checkCodeRspVO = new CheckCodeRspVO();
		checkCodeRspVO.setCheckCodeKey(checkCodeKey);
		checkCodeRspVO.setCheckCode(captchaBase64);
		return getSuccessResponseVO(checkCodeRspVO);
	}

	@PostMapping("/register")
	public ResponseVO register(@Validated WebRegisterReqVO reqVO) {
		try {
			// 校验验证码
			validateCheckCode(reqVO.getCheckCodeKey(), reqVO.getCheckCode());

			// 注册
			userInfoService.register(reqVO.getEmail(), reqVO.getRegisterPassword(), reqVO.getNickName());

			return getSuccessResponseVO(null);
		} finally {
			redisComponent.deleteCheckCodeByKey(reqVO.getCheckCodeKey());
		}
	}

	@PostMapping("/login")
	public ResponseVO login(@Validated WebLoginReqVO reqVO, HttpServletResponse response) {

		try {
			// 校验验证码
			validateCheckCode(reqVO.getCheckCodeKey(), reqVO.getCheckCode());

			// 获取IP
			String ipAddr = getIpAddr();
			TokenUserInfoDto tokenUserInfoDto = userInfoService.login(reqVO.getEmail(), reqVO.getPassword(), ipAddr);
			saveToken2Cookie(response, tokenUserInfoDto.getToken());
			return getSuccessResponseVO(tokenUserInfoDto);
		} finally {
			redisComponent.deleteCheckCodeByKey(reqVO.getCheckCodeKey());
		}
	}

	/**
	 * 自动登录, 续签token
	 * @return
	 */
	@PostMapping("/autoLogin")
	public ResponseVO autoLogin(HttpServletResponse response) {
		TokenUserInfoDto tokenUserInfoDto = getTokenUserInfoDto();
		if (ObjectUtils.isEmpty(tokenUserInfoDto)) {
			return getSuccessResponseVO(null);
		}
		if (tokenUserInfoDto.getExpireAt() - System.currentTimeMillis() < Constants.REDIS_KEY_EXPIRES_ONE_DAY) {
			// 续签token
			redisComponent.saveTokenInfo(tokenUserInfoDto);
		}
		saveToken2Cookie(response, tokenUserInfoDto.getToken());
		return getSuccessResponseVO(tokenUserInfoDto);
	}

	@PostMapping("/logout")
	@GlobalInterceptor(checkLogin = true)
	public ResponseVO logout(HttpServletResponse response) {
		cleanToken(response);
		return getSuccessResponseVO(null);
	}


	private void validateCheckCode(String checkCodeKey, String checkCode) {
		String redisCheckCode = redisComponent.getCheckCodeByKey(checkCodeKey);
		if (StringTools.isEmpty(redisCheckCode)) {
			throw new BusinessException("验证码已过期，请重新获取");
		}

		if (!redisCheckCode.equalsIgnoreCase(checkCode)) {
			throw new BusinessException("验证码错误");
		}
	}

	@PostMapping("/getUserCountInfo")
	@GlobalInterceptor(checkLogin = true)
	public ResponseVO getUserCountInfo() {
		TokenUserInfoDto tokenUserInfoDto = getTokenUserInfoDto();
		UserFocusQuery query = new UserFocusQuery();
		/**
		 * 0: 关联关注
		 * 1: 关联粉丝
		 */
		query.setQueryType(QueryUserFocusEnum.QUERY_FOCUS.getCode());
		query.setUserId(tokenUserInfoDto.getUserId());
		Integer focusCount = userFocusService.findCountByParam(query);

		query.setQueryType(QueryUserFocusEnum.QUERY_FANS.getCode());
		Integer fansCount = userFocusService.findCountByParam(query);

		UserInfo userInfo = userInfoService.getUserInfoByUserId(tokenUserInfoDto.getUserId());

		AccountGetUserCountInfoRspVO rspVO = new AccountGetUserCountInfoRspVO();
		rspVO.setFocusCount(focusCount);
		rspVO.setFansCount(fansCount);
		rspVO.setCurrentCoinCount(userInfo.getCurrentIconCount());

		return getSuccessResponseVO(rspVO);
	}

}